namespace Destra.Common.Caching
{
    /// <summary>
    /// Custom ConfigSection class
    /// </summary>
    public class CacheConfiguration : System.Configuration.IConfigurationSectionHandler
    {
        private static CacheConfiguration _instance = null;

        /// <summary>
        /// Singleton access for the CacheConfiguration.
        /// </summary>
        public static CacheConfiguration Instance
        {
            get
            {
                if (_instance == null)
                {
                    _instance = (CacheConfiguration)System.Configuration.ConfigurationManager.GetSection("CacheConfiguration");
                }
                return _instance;
            }
        }

        #region Configuration Section Attribute Properties

        private int _databasePollSeconds;

        /// <summary>
        /// The number of seconds between database polls. This uses the same database triggers/table as the ASP.NET
        /// database dependency. If the DatabasePollSeconds is set to 0 no database polling is performed. If the
        /// DatabasePollSeconds is set below 15 seconds the system will override the value and set it to 15 seconds.
        /// </summary>
        public int DatabasePollSeconds
        {
            get { return _databasePollSeconds; }
            set { _databasePollSeconds = value; }
        }

        private string _applicationName;

        /// <summary>
        /// Returns the applicationName attribute value as defined in the ConfigSection.
        /// </summary>
        public string ApplicationName
        {
            get { return _applicationName; }
            set { _applicationName = value; }
        }

        private string _rootPath;

        /// <summary>
        /// Returns the rootPath attribute value as defined in the ConfigSection.
        /// </summary>
        public string RootPath
        {
            get { return _rootPath; }
            set
            {
                _rootPath = value;
                if (!_rootPath.EndsWith(@"\"))
                {
                    _rootPath += @"\";
                }
            }
        }

        #endregion

        #region IConfigurationSectionHandler Members

        /// <summary>
        /// Helper class for a custom configuration section
        /// </summary>
        internal static class ConfigurationHelper
        {

            internal static int GetEnumValue(System.Xml.XmlNode node, string attribute, System.Type enumType)
            {
                System.Xml.XmlNode nodeAttribute = node.Attributes.RemoveNamedItem(attribute);
                if (nodeAttribute == null)
                {
                    throw new System.Configuration.ConfigurationErrorsException("Attribute required: " + attribute);
                } if (System.Enum.IsDefined(enumType, nodeAttribute.Value))
                {
                    return (int)System.Enum.Parse(enumType, nodeAttribute.Value);
                }
                else
                {
                    throw new System.Configuration.ConfigurationErrorsException("Invalid Level", nodeAttribute);
                }
            }

            internal static string GetStringValue(System.Xml.XmlNode node, string attribute)
            {
                System.Xml.XmlNode nodeAttribute = node.Attributes.RemoveNamedItem(attribute);
                if (nodeAttribute == null)
                {
                    throw new System.Configuration.ConfigurationErrorsException("Attribute required: " + attribute);
                }
                else
                {
                    return nodeAttribute.Value;
                }
            }
        }

        /// <summary>
        /// Create method for the custom ConfigSection. 
        /// </summary>
        /// <param name="parent"></param>
        /// <param name="configContext"></param>
        /// <param name="section">applicationName, rootPath</param>
        /// <returns></returns>
        public object Create(object parent, object configContext, System.Xml.XmlNode section)
        {
            CacheConfiguration configuration = new CacheConfiguration();
            configuration.ApplicationName = ConfigurationHelper.GetStringValue(section, "applicationName");
            configuration.RootPath = ConfigurationHelper.GetStringValue(section, "rootPath");
            configuration.DatabasePollSeconds = int.Parse(ConfigurationHelper.GetStringValue(section, "databasePollSeconds"));
            if (!configuration.DatabasePollSeconds.Equals(0) && configuration.DatabasePollSeconds < 15)
            {
                configuration.DatabasePollSeconds = 15;
            }

            return configuration;
        }

        #endregion

    }
}